package com.motu.monstercity.server.game.logichandler;

import com.motu.monstercity.module.common.iap.IapGift;
import com.motu.monstercity.module.common.network.RequestParam;
import com.motu.monstercity.module.common.servermanager.ServerManager;
import com.motu.monstercity.protocol.Common;
import com.motu.monstercity.protocol.Common.PBUserData;
import com.motu.monstercity.protocol.CsGameAct;
import com.motu.monstercity.protocol.CsGameAct.*;
import com.motu.monstercity.server.game.base.AllParam;
import com.motu.monstercity.server.game.base.CommonUtils;
import com.motu.monstercity.server.game.base.ProtoDataUtils;
import com.motu.monstercity.server.game.commondata.act.*;
import com.motu.monstercity.server.game.commondata.bag.BagConstant;
import com.motu.monstercity.server.game.commondata.bag.Box;
import com.motu.monstercity.server.game.commondata.bag.ItemId;
import com.motu.monstercity.server.game.commondata.iap.PrivilegeCard;
import com.motu.monstercity.server.game.commondata.iap.PrivilegeCardConstant;
import com.motu.monstercity.server.game.commondata.rank.RankConstant;
import com.motu.monstercity.server.game.commondata.skill.SkillConstant;
import com.motu.monstercity.server.game.commondata.system.SystemConstant;
import com.motu.monstercity.server.game.log.LogType;
import com.motu.monstercity.server.game.logic.*;
import com.motu.monstercity.server.game.userdata.*;
import com.motu.monstercity.server.game.userdata.UserActDiscountGift;
import com.motu.vertx.module.utility.toolset.ErrorWord;
import com.motu.vertx.module.utility.toolset.TimeUtils;
import com.motu.vertx.module.utility.toolset.Tool;
import io.vertx.core.json.JsonArray;
import org.bouncycastle.util.Strings;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

public class ActHandler {


	// CMD_GAME_ACT_RESGISTER_SIGN_REWARD = 80010; // 七日签到领取奖励
	public static Object CMD_GAME_ACT_RESGISTER_SIGN_REWARD(RequestParam clientParam) throws Exception {
		CSGameActResgisterSignRewardRequest request = CSGameActResgisterSignRewardRequest.parseFrom(clientParam.getData());
		CSGameActResgisterSignRewardResponse.Builder response = CSGameActResgisterSignRewardResponse.newBuilder();
		long userId = clientParam.getUserId();
		int dayIndex = request.getDayIndex();
		UserExtInfo userExtInfo = GameUser.getUserExtInfo(userId);
		int diffDay = TimeUtils.getDiffDay(userExtInfo.getRegisterTime()) + 1;//因为注册当天即可领取第一天奖励
		UserInfo userInfo = GameUser.getUserInfo(userId);
		PBUserData.Builder pbUserData = response.getUserBuilder();
		UserSign userSign = ActManager.getUserSign(userId);
		JsonArray resgisterSignRewardArray = userSign.getResgisterSignRewardArray();
		List<RegisterSignReward> registerSignRewardList = new ArrayList<>();//可领取的奖励列表
		if(dayIndex == 0) {
			//一件领取
			int dayNum = Math.min(diffDay,ActManager.getRegisterSignRewardMap().size());
			for (int i = 1; i <= dayNum; i++) {
				if (i > dayNum) {
					break;
				}
				RegisterSignReward registerSignReward = ActManager.getRegisterSignReward(i);
				if (!Tool.isInList(resgisterSignRewardArray,i)) {
					resgisterSignRewardArray.add(i);
					registerSignRewardList.add(registerSignReward);
				}
			}
			if(registerSignRewardList.size() == 0){
				return ErrorWord.REPEATED_OPERATION;
			}
			userSign.putResgisterSignReward(resgisterSignRewardArray.toString());
		} else {
			RegisterSignReward registerSignReward = ActManager.getRegisterSignReward(dayIndex);
			if (registerSignReward == null) {
				return ErrorWord.WRONG_STATUS;
			}
			if (diffDay < dayIndex) {
				return ErrorWord.WRONG_STATUS;
			}
			if (Tool.isInList(resgisterSignRewardArray,dayIndex)) {
				return ErrorWord.REPEATED_OPERATION;
			}
			resgisterSignRewardArray.add(dayIndex);
			userSign.putResgisterSignReward(resgisterSignRewardArray.toString());
			registerSignRewardList.add(registerSignReward);
		}
		userSign.update();
		for(RegisterSignReward registerSignReward : registerSignRewardList) {
			RewardManager.addReward(userInfo, registerSignReward.getRewardItemList(), pbUserData, LogType.RESGISTER_SIGN_REWARD,registerSignReward.getDayNum());
		}
		ProtoDataUtils.updatePBUserData(pbUserData, userSign);
		return response;
	}

	// CMD_GAME_ACT_HUNDRED_DRAW_INFO = 80011; // 新手百抽活动信息
	public static Object CMD_GAME_ACT_HUNDRED_DRAW_INFO(RequestParam clientParam) throws Exception {
		CSGameActHundredDrawInfoRequest request = CSGameActHundredDrawInfoRequest.parseFrom(clientParam.getData());
		CSGameActHundredDrawInfoResponse.Builder response = CSGameActHundredDrawInfoResponse.newBuilder();
		long userId = clientParam.getUserId();
		UserExtInfo userExtInfo = GameUser.getUserExtInfo(userId);
		UserCommonAct userCommonAct = ActManager.getUserCommonAct(userId);
		PBUserData.Builder pbUserData = response.getUserBuilder();
		ActManager.updateHundredDraw(pbUserData, userCommonAct, userExtInfo, true);
		return response;
	}

	// CMD_GAME_ACT_HUNDRED_DRAW_GET_REWARD = 80012; // 领取新手百抽奖励
	public static Object CMD_GAME_ACT_HUNDRED_DRAW_GET_REWARD(RequestParam clientParam) throws Exception {
		long userId = clientParam.getUserId();
		UserInfo userInfo = GameUser.getUserInfo(userId);
		if (!SystemManager.checkModuleOpen(userInfo, SystemConstant.SYSTEM_MODULE_ID_HUNDRED_DRAW)) {
			return ErrorWord.MODULE_LOCKED;
		}
		UserExtInfo userExtInfo = GameUser.getUserExtInfo(userId);
		UserCommonAct userCommonAct = ActManager.getUserCommonAct(userId);
		int[] actTenDayGift = ActManager.getActTenDayGiftInfo(userExtInfo.getRegisterTime());
		if (actTenDayGift == null || actTenDayGift.length <= 0){
			return ErrorWord.NOT_DATA;// 奖励未配置
		}
		CsGameAct.CSGameActHundredDrawGetRewardRequest request = CsGameAct.CSGameActHundredDrawGetRewardRequest.parseFrom(clientParam.getData());
		JsonArray hundredDrawGetArray = userCommonAct.getHundredDrawGetArray();
		JsonArray chargeHundredDrawGetArray = userCommonAct.getChargeHundredDrawGetArray(); // 充值百抽
		JsonArray hundredChargeArray = userCommonAct.getHundredChargeArray(); // 充值记录
		// 领取天数
//		int day = request.getDay();
//		if (day < 1 || day > actTenDayGift.length / 2){
//			return ErrorWord.BAD_PARAM;// 上行参数错误
//		}
		// 获取当前是登录的第几天
		int curLoginDay = userExtInfo.getLoginDayCount();
		// 判断领取天数是否满足登录天数要求或者领取天数是否超过了领取奖励的天数
//		if (day > curLoginDay){
//			return ErrorWord.INVALID_OPERATION;
//		}
//		if (Tool.isInList(hundredDrawGetArray, day)){
//			if (!Tool.isInList(hundredChargeArray, day) || Tool.isInList(chargeHundredDrawGetArray, day)) {
//				return ErrorWord.REPEATED_OPERATION;// 重复领取
//			}
//		}
		CsGameAct.CSGameActHundredDrawGetRewardResponse.Builder response = CsGameAct.CSGameActHundredDrawGetRewardResponse.newBuilder();
		PBUserData.Builder pbUserData = response.getUserBuilder();
		boolean normalReward = false, chargeReward = false;
		for (int i = 0; i < actTenDayGift.length / 2; i++) {
			int rewardDay = i + 1;
			if (curLoginDay < rewardDay) {
				break;
			}
			int itemId = actTenDayGift[i * 2];
			long itemNum = actTenDayGift[i * 2 + 1];
			if (!Tool.isInList(hundredDrawGetArray, rewardDay)) {
				hundredDrawGetArray.add(rewardDay);
				RewardManager.addReward(userInfo, itemId, itemNum, pbUserData, LogType.ACT_HUNDRED_DRAW_REWARD);
				normalReward = true;
			}
			if (Tool.isInList(hundredChargeArray, rewardDay) && !Tool.isInList(chargeHundredDrawGetArray, rewardDay)) {
				chargeHundredDrawGetArray.add(rewardDay);
				RewardManager.addReward(userInfo, itemId, itemNum, pbUserData, LogType.ACT_HUNDRED_DRAW_REWARD);
				chargeReward = true;
			}
		}
		if (!normalReward && !chargeReward) {
			return ErrorWord.ALREADY_MAX;
		}
		if (normalReward) {
			userCommonAct.putHundredDrawGet(hundredDrawGetArray.toString());
		}
		if (chargeReward) {
			userCommonAct.putChargeHundredDrawGet(chargeHundredDrawGetArray.toString());
		}
		// 领奖
//		int itemId = actTenDayGift[(day - 1) * 2];
//		long num = actTenDayGift[(day - 1) * 2 + 1];
//		RewardManager.addReward(userInfo, itemId, num, pbUserData, LogType.ACT_HUNDRED_DRAW_REWARD);
//		// 更新领取状态
//		if (!Tool.isInList(hundredDrawGetArray, day)) {
//			hundredDrawGetArray.add(day);
//			userCommonAct.putHundredDrawGet(hundredDrawGetArray.toString());
//		} else {
//			chargeHundredDrawGetArray.add(day);
//			userCommonAct.putChargeHundredDrawGet(chargeHundredDrawGetArray.toString());
//		}
		userCommonAct.update();
		ActManager.updateHundredDraw(pbUserData, userCommonAct, null, false);
		return response;
	}

	// CMD_GAME_ACT_DAILY_SIGN_INFO = 80013; // 每日签到界面
	public static Object CMD_GAME_ACT_DAILY_SIGN_INFO(RequestParam clientParam) throws Exception {
		CsGameAct.CSGameActDailySignInfoResponse.Builder response = CsGameAct.CSGameActDailySignInfoResponse.newBuilder();
		UserDailySign userDailySign = ActManager.getUserDailySign(clientParam.getUserId());
		PBUserData.Builder pbUserData = response.getUserBuilder();
		ProtoDataUtils.updatePBUserData(pbUserData, userDailySign, true);
		return response;
	}

	// CMD_GAME_ACT_DAILY_SIGN_REWARD = 80014; // 每日签到领奖
	public static Object CMD_GAME_ACT_DAILY_SIGN_REWARD(RequestParam clientParam) throws Exception {
		CsGameAct.CSGameActDailySignRewardResponse.Builder response = CsGameAct.CSGameActDailySignRewardResponse.newBuilder();
		PBUserData.Builder pbUserData = response.getUserBuilder();
		long userId = clientParam.getUserId();
		UserDailySign userDailySign = ActManager.getUserDailySign(userId);
		// 没有奖励可领
		if (userDailySign.isReward()) {
			return ErrorWord.NOT_DATA;
		}
		DailySign dailySign = ActManager.getDailySign(userDailySign.getType(), userDailySign.getDay());
		// 奖励未配置
		if (dailySign == null) {
			return ErrorWord.NOT_DATA_1;
		}
		UserInfo userInfo = GameUser.getUserInfo(userId);
		RewardManager.addReward(userInfo, dailySign.getRewardList(), pbUserData, LogType.ACT_DAILY_SIGN);
		if (!userDailySign.isReward()) {
			userDailySign.putIsReward(UserDailySign.YES);
		} else {
			userDailySign.putIsAdReward(UserDailySign.YES);
		}
		userDailySign.update();
		ProtoDataUtils.updatePBUserData(pbUserData, userDailySign);
		return response;
	}

	// CMD_GAME_ACT_DAILY_SIGN_WATCH_AD = 80015; // 每日签到观看广告
	public static Object CMD_GAME_ACT_DAILY_SIGN_WATCH_AD(RequestParam clientParam) throws Exception {
		CSGameActDailySignWatchAdResponse.Builder response = CSGameActDailySignWatchAdResponse.newBuilder();
		PBUserData.Builder pbUserData = response.getUserBuilder();
		long userId = clientParam.getUserId();
		UserDailySign userDailySign = ActManager.getUserDailySign(userId);
		if (!userDailySign.isReward()) {
			return ErrorWord.WRONG_STATUS;
		}
		if (userDailySign.isWatchAd()) {
			return ErrorWord.REPEATED_OPERATION;
		}
		UserAdvideo userAdvideo = GameUser.getUserAdvideo(userId);
		userAdvideo.putAdStartTime(TimeUtils.getCurTime());
		String adcode = UUID.randomUUID().toString();//生成唯一码
		userAdvideo.putAdCode(adcode);
		userAdvideo.update();
		ProtoDataUtils.updatePBUserData(pbUserData, userAdvideo);
		return response;
	}

	// CMD_GAME_ACT_DAILY_SIGN_AD_COMPLETE = 80016; // 每日签到完成看广告
	public static Object CMD_GAME_ACT_DAILY_SIGN_AD_COMPLETE(RequestParam clientParam) throws Exception {
		CSGameActDailySignAdCompleteRequest request = CSGameActDailySignAdCompleteRequest.parseFrom(clientParam.getData());
		CSGameActDailySignAdCompleteResponse.Builder response = CSGameActDailySignAdCompleteResponse.newBuilder();
		PBUserData.Builder pbUserData = response.getUserBuilder();
		long userId = clientParam.getUserId();
		String adCode = request.getAdCode();
		UserAdvideo userAdvideo = GameUser.getUserAdvideo(userId);
		if (!GameUser.checkAdVideo(userAdvideo, adCode)) {// 观看时间不足，或是唯一码不对
			return ErrorWord.INVALID_OPERATION;
		}
		userAdvideo.putAdCode("");
		userAdvideo.putAdStartTime(0);
		userAdvideo.update();
		ProtoDataUtils.updatePBUserData(pbUserData, userAdvideo);
		UserDailySign userDailySign = ActManager.getUserDailySign(userId);
		DailySign dailySign = ActManager.getDailySign(userDailySign.getType(), userDailySign.getDay());
		if (dailySign == null) {
			return ErrorWord.NOT_DATA_1;
		}
		UserInfo userInfo = GameUser.getUserInfo(userId);
		RewardManager.addReward(userInfo, dailySign.getAdvideoReward(), pbUserData, LogType.ACT_DAILY_SIGN);
		userDailySign.putIsWatchAd(UserDailySign.YES);
		userDailySign.update();
		ProtoDataUtils.updatePBUserData(pbUserData, userAdvideo);
		return response;
	}


	// CMD_GAME_ACT_DAILY_SCREEN_REWARD = 80050; // 每日放映领取奖励
	public static Object CMD_GAME_ACT_DAILY_SCREEN_REWARD(RequestParam clientParam) throws Exception {
		CSGameActDailyScreenRewardRequest request = CSGameActDailyScreenRewardRequest.parseFrom(clientParam.getData());
		CSGameActDailyScreenRewardResponse.Builder  response = CSGameActDailyScreenRewardResponse.newBuilder();
		long userId = clientParam.getUserId();

		UserInfo userInfo = GameUser.getUserInfo(userId);
		int serverId = userInfo.getServerId();

		if (!SystemManager.checkModuleOpen(userInfo, SystemConstant.SYSTEM_MODULE_ID_DAILY_SCREEN)) {
			return ErrorWord.MODULE_LOCKED;
		}

		PBUserData.Builder pbUserData = response.getUserBuilder();
		UserActDailyScreen userActDailyScreen = ActManager.getUserActDailyScreen(userId);

		JsonArray receiveList = userActDailyScreen.getReceiveListArray();
		List<RewardItem> rewardItemList = new ArrayList<>();

		int serverOpenDay = ServerManager.getServerOpenDay(serverId);
		int subGiftSize = AllParam.BENEFIT_AD_SUB_AIP_GIFT_ID.length;
		int totalNum = AllParam.BENEFIT_AD_AIP_FREE_NUM + AllParam.BENEFIT_AD_AIP_AD_NUM; // 领取免费和广告的总数

		// 检查配置是否正确
		if (AllParam.BENEFIT_AD_GIFT == 0 || totalNum == 0 || subGiftSize != (AllParam.BENEFIT_AD_GIFT * totalNum)) {
			return ErrorWord.BAD_PARAM;
		}

		// 按照开服天数获取对应的IAP商品giftId
		int index = serverOpenDay % AllParam.BENEFIT_AD_GIFT;
		int subIapGiftId;
		for (int i = 0; i < totalNum; i++) { // 检查是否存在对应的IAP商品
			subIapGiftId = AllParam.BENEFIT_AD_SUB_AIP_GIFT_ID[totalNum * index + i];
			IapGift iapGift = IapManager.getIapGift(subIapGiftId);
			if (iapGift == null) {
				return ErrorWord.ITEM_NOT_EXIST;
			}

			if (iapGift.getType() != IapGift.TYPE_BENEFIT_AD_GIFT) { // 检查是否为广告连锁礼包类型
				return ErrorWord.BAD_PARAM;
			}
		}

		// 检查是否已经领取过
		if (receiveList.size() >= totalNum) {
			return ErrorWord.REPEATED_OPERATION;
		}

		// 执行逻辑
		// 检查是否为白银卡玩家
		boolean isAvoidAd = false; // 是否免广告
		UserPrivilegeCard userPrivilegeCard1 = IapManager.getUserPrivilegeCard(userId, PrivilegeCardConstant.PRIVILEAGE_CARD_TYPE_1);
		if (userPrivilegeCard1 != null && !userPrivilegeCard1.isExpired()) {
			PrivilegeCard privilegeCard = IapManager.getPrivilegeCard(userPrivilegeCard1.getType());
			if (privilegeCard.getAd() == 1) { // 可免广告
				isAvoidAd = true;
			}
		}

		if (isAvoidAd) {
			// 白银卡玩家一次性领取所有挡位
			for (int i = 0; i < totalNum; i++) {
				if (!Tool.isInList(receiveList, i)) {
					receiveList.add(i);
					addRewardItems(AllParam.BENEFIT_AD_SUB_AIP_GIFT_ID[totalNum * index + i], rewardItemList);
				}
			}
		} else {
			int nextRewardIndex = receiveList.size(); // 获取下一个未领取的挡位
			if (nextRewardIndex >= AllParam.BENEFIT_AD_AIP_FREE_NUM) { // 看广告的领取
				String adCode = request.getAdCode();
				UserAdvideo userAdvideo = GameUser.getUserAdvideo(userId);
				if (!GameUser.checkAdVideo(userAdvideo, adCode)) {
					return ErrorWord.WRONG_STATUS;
				}
				// 重新设置观看时间
				userAdvideo.resetAdvideoData(pbUserData);
			}
			receiveList.add(nextRewardIndex);
			addRewardItems(AllParam.BENEFIT_AD_SUB_AIP_GIFT_ID[totalNum * index + nextRewardIndex], rewardItemList);
		}

		// 更新用户数据和返回奖励
		if (!rewardItemList.isEmpty()) {
			userActDailyScreen.putReceiveList(receiveList.toString());
			userActDailyScreen.update();
			RewardManager.addReward(userInfo, rewardItemList, pbUserData, LogType.DAILY_SCREEN_REWARD);
			ProtoDataUtils.updatePBUserData(pbUserData, userActDailyScreen);
		}

		return response;
	}

	// 添加每日放映的奖励
	private static void addRewardItems(int realIapGiftId, List<RewardItem> rewardItemList) {
		IapGift iapGift = IapManager.getIapGift(realIapGiftId);
		if (iapGift != null) {
			rewardItemList.addAll(CommonUtils.takeReawrdItemFromStr(iapGift.getReward()));
		}
	}

	// CMD_GAME_ACT_DAILY_SUPPLY_REWARD = 80054; // 每日补给领取奖励
	public static Object CMD_GAME_ACT_DAILY_SUPPLY_REWARD(RequestParam clientParam) throws Exception {
		CSGameActDailySupplyRewardRequest request = CSGameActDailySupplyRewardRequest.parseFrom(clientParam.getData());
		CSGameActDailySupplyRewardResponse.Builder  response = CSGameActDailySupplyRewardResponse.newBuilder();
		long userId = clientParam.getUserId();
		int index = request.getGiftIndex(); // 领取哪一档的奖励下标

		UserInfo userInfo = GameUser.getUserInfo(userId);
		int serverId = userInfo.getServerId();

		if (!SystemManager.checkModuleOpen(userInfo, SystemConstant.SYSTEM_MODULE_ID_DAILY_SUPPLY)) {
			return ErrorWord.MODULE_LOCKED;
		}

		PBUserData.Builder pbUserData = response.getUserBuilder();
		UserActDailySupply userActDailySupply = ActManager.getUserActDailySupply(userId);

		JsonArray receiveList = userActDailySupply.getReceiveListArray();
		List<RewardItem> rewardItemList = new ArrayList<>();

		// 首先判断时间
		boolean checkSupplyTime = checkSupplyTime(index);
		if (!checkSupplyTime){
			return ErrorWord.INVALID_OPERATION;
		}
		// 检查是否已经领取过
		if (receiveList.contains(index)) {
			return ErrorWord.REPEATED_OPERATION;
		}
		if (index == 1) {
			rewardItemList = RewardManager.itemsToList(AllParam.DAILY_SUPPLY_GIFT_1);
		} else if (index == 2) {
			rewardItemList = RewardManager.itemsToList(AllParam.DAILY_SUPPLY_GIFT_2);
		} else if (index == 3) {
			rewardItemList = RewardManager.itemsToList(AllParam.DAILY_SUPPLY_GIFT_3);
		}
		// 更新用户数据和返回奖励
		if (!rewardItemList.isEmpty()) {
			receiveList.add(index);
			userActDailySupply.putReceiveList(receiveList.toString());
			userActDailySupply.update();
			RewardManager.addReward(userInfo, rewardItemList, pbUserData, LogType.DAILY_SUPPLY_REWARD);
			ProtoDataUtils.updatePBUserData(pbUserData, userActDailySupply);
		}

		return response;
	}

	// 校验每日补给领奖是否在有效时间内
	public static boolean checkSupplyTime(int giftIndex){
		long curTime = TimeUtils.getCurTime();
		String timeStr = "";
		if (giftIndex == 1) {
			timeStr = AllParam.DAILY_SUPPLY_GIFT_TIME_1;
		} else if (giftIndex == 2) {
			timeStr = AllParam.DAILY_SUPPLY_GIFT_TIME_2;
		} else if (giftIndex == 3) {
			timeStr = AllParam.DAILY_SUPPLY_GIFT_TIME_3;
		}
		if (timeStr.isEmpty())	{
			return false;
		}
		String[] data = Strings.split(timeStr, ';');
		long startTime = TimeUtils.getTodayOneTime(data[0]); // 开始时间
		long endTime = TimeUtils.getTodayOneTime(data[1]); // 开始时间
        return curTime >= startTime && curTime <= endTime;
    }

	// CMD_GAME_ACT_CONVENTION_MAIN_INFO = 80060; 万能活动信息(排行榜信息 每次打开请求,切换页签也请求)
	public static Object CMD_GAME_ACT_CONVENTION_MAIN_INFO(RequestParam clientParam) throws Exception {
		CSGameActConventionMainInfoRequest request = CSGameActConventionMainInfoRequest.parseFrom(clientParam.getData());
		CSGameActConventionMainInfoResponse.Builder response = CSGameActConventionMainInfoResponse.newBuilder();
		long userId = clientParam.getUserId();
		UserInfo userInfo = GameUser.getUserInfo(userId);
		UserActConvention userActConvention = ActConventionManager.getUserActConvention(userInfo.getId());
		long actId = userActConvention.getActId();
		int serverId = userInfo.getServerId();
		String dateKey = String.valueOf(actId);
		Act act = ActManager.getAct(actId);
		if (act == null || !act.isShowtime(serverId)) {
			return ErrorWord.ACT_NOT_OPEN;
		}
		int type = request.getType();
		int rankType;
		if (type == 1) {
			rankType = RankConstant.ACTIVITY_RANK_CONVENTION;
		} else if (type == 2) {
			rankType = RankConstant.ACTIVITY_CROSS_RANK_CONVENTION;
			serverId = ServerManager.getWarZoneId(serverId);
		} else {
			return ErrorWord.BAD_PARAM;
		}

		Common.PBRankInfo.Builder pbRankInfo = Common.PBRankInfo.newBuilder();
		List<Common.PBRankMember.Builder> memberList = RankManager.getRankMemberList(rankType, serverId, dateKey, AllParam.ACT_CONVENTION_RANK_MEMBER_LIST_MAX);
		for (Common.PBRankMember.Builder pbRankMember : memberList) {
			pbRankInfo.addMembers(pbRankMember.build());
		}

		int myRank = RankManager.getMyRank(rankType, serverId, userId, dateKey);
		pbRankInfo.setMyRank(myRank);
		long myScore = RankManager.getMyScore(rankType, serverId, userId, dateKey);
		pbRankInfo.setMyScore(myScore);
		response.setType(type);
		response.setPbRankInfo(pbRankInfo.build());

		return response;
	}

	// CMD_GAME_ACT_CONVENTION_TASK_LIST = 80061; // 获取任务列表 (每次打开请求)
	public static Object CMD_GAME_ACT_CONVENTION_TASK_LIST(RequestParam clientParam) throws Exception {
		CSGameActConventionTaskListResponse.Builder response = CSGameActConventionTaskListResponse.newBuilder();
		long userId = clientParam.getUserId();
		UserInfo userInfo = GameUser.getUserInfo(userId);
		UserActConvention userActConvention = ActConventionManager.getUserActConvention(userInfo.getId());
		long actId = userActConvention.getActId();
		Act act = ActManager.getAct(actId);
		int serverId = userInfo.getServerId();
		if (act == null || !act.isShowtime(serverId)) {
			return ErrorWord.ACT_NOT_OPEN;
		}

		PBUserData.Builder pbUserData = response.getUserBuilder();
		List<UserActConventionTask> userActConventionTaskList = ActConventionManager.getUserActConventionTaskList(userId);
		for (UserActConventionTask userActConventionTask : userActConventionTaskList) {
			ProtoDataUtils.updatePBUserData(pbUserData, userActConventionTask, true);
		}
		return response;
	}

	// CMD_GAME_ACT_CONVENTION_OPEN_BOX = 80062; // 万能活动-开宝箱
	public static Object CMD_GAME_ACT_CONVENTION_OPEN_BOX(RequestParam clientParam) throws Exception {
		CSGameActConventionOpenBoxRequest request = CSGameActConventionOpenBoxRequest.parseFrom(clientParam.getData());
		CSGameActConventionOpenBoxResponse.Builder response = CSGameActConventionOpenBoxResponse.newBuilder();
		long userId = clientParam.getUserId();
		int boxId = request.getBoxId();
		int boxNum = request.getBoxNum();
		int rankType = request.getRankType();

		// 参数校验
		if (boxNum < 1 || boxNum > 10) {
			return ErrorWord.BAD_PARAM;
		}

		// 获取宝箱信息
		Box box = BagManager.getBox(boxId);
		if (box == null) {
			return ErrorWord.NOT_DATA;
		}

		// 只有3类型宝箱才可打开
		if (box.getType() != BagConstant.BOX_REWARD_TYPE_3) {
			return ErrorWord.BAD_PARAM;
		}

		// 宝箱类型3，必得奖励不能为空
		UserInfo userInfo = GameUser.getUserInfo(userId);
		if (box.getReward() == null || box.getReward().isEmpty() || !ActConventionManager.isOpenBox(userInfo, boxId)) {
			return ErrorWord.BAD_PARAM;
		}

		// 获取用户信息
		UserActConvention userActConvention = ActConventionManager.getUserActConvention(userInfo.getId());
		long actId = userActConvention.getActId();
		Act act = ActManager.getAct(actId);
		if (act == null || !act.isCloseTime()) {
			return ErrorWord.ACT_NOT_OPEN;
		}

		ActConvention actConvention = ActConventionManager.getActConvention(act.getActParamValue());
		if (actConvention == null) {
			return ErrorWord.NOT_DATA;
		}

		PBUserData.Builder pbUserData = response.getUserBuilder();
		long userItemNum = BagManager.getUserItemNum(userInfo, boxId);
		if (userItemNum < boxNum) {
			return ErrorWord.ITEM_LACK;// 数量不足
		}

		// 执行逻辑
		RewardManager.subReward(userInfo, boxId, boxNum, pbUserData, LogType.CONVENTION_OPEN_BOX);//扣除宝箱

		// 计算总奖励
		List<RewardItem> totalRewardItems = BagManager.takeBoxRandomRewardAndMustReward(box, boxNum); // 获取宝箱随机奖励+必得奖励
		int skillAdd = SkillManager.getSkillMoudleAdd(userId, SkillConstant.EFFECT_TYPE_37, actConvention.getType());// 万能活动开宝箱时获得积分 增加 百分比  effect_param,配置1或2，对应act_convention 的type值
		if (skillAdd > 0) {
			for (RewardItem rewardItem : totalRewardItems) {
				if (rewardItem.getItemId() == ItemId.TYPE_ACT_CONVENTION_SCORE) {
					long newNum = CommonUtils.countPerValue(rewardItem.getItemNum(), skillAdd);
					rewardItem.setItemNum(newNum);
				}
			}
		}

		// 更新用户奖励和积分
		RewardManager.addReward(userInfo, totalRewardItems, pbUserData, LogType.CONVENTION_OPEN_BOX);
		int serverId = userInfo.getServerId();
		int myRank;
		long score;
		String dateKey = String.valueOf(actId);

		if (rankType == 1) { // 取本服排行榜
			myRank = RankManager.getMyRank(RankConstant.ACTIVITY_RANK_CONVENTION, serverId, userId, dateKey);
			score = RankManager.getMyScore(RankConstant.ACTIVITY_RANK_CONVENTION, serverId, userId, dateKey);
		} else {
			int groupId = ServerManager.getWarZoneId(serverId);
			myRank = RankManager.getMyRank(RankConstant.ACTIVITY_CROSS_RANK_CONVENTION, groupId, userId, dateKey);
			score = RankManager.getMyScore(RankConstant.ACTIVITY_CROSS_RANK_CONVENTION, groupId, userId, dateKey);
		}
		response.setMyRank(myRank);
		response.setScore(score);
		response.setRankType(rankType);
		return response;
	}

	// CMD_GAME_ACT_CONVENTION_RECEIVE_TASK_REWARD = 80063; // 领取任务奖励
	public static Object CMD_GAME_ACT_CONVENTION_RECEIVE_TASK_REWARD(RequestParam clientParam) throws Exception {
		CSGameActConventionReceiveTaskRewardRequest request = CSGameActConventionReceiveTaskRewardRequest.parseFrom(clientParam.getData());
		CSGameActConventionReceiveTaskRewardResponse.Builder response = CSGameActConventionReceiveTaskRewardResponse.newBuilder();
		long userId = clientParam.getUserId();
		int taskDbId = request.getTaskDbId();

		UserInfo userInfo = GameUser.getUserInfo(userId);
		UserActConvention userActConvention = ActConventionManager.getUserActConvention(userInfo.getId());
		long actId = userActConvention.getActId();
		int serverId = userInfo.getServerId();
		Act act = ActManager.getAct(actId);
		if (act == null || !act.isShowtime(serverId)) {
			return ErrorWord.ACT_NOT_OPEN;
		}

		// 获取任务信息
		ActConventionTask actConventionTask = ActConventionManager.getActConventionTask(taskDbId);
		if (actConventionTask == null) {
			return ErrorWord.NOT_DATA;
		}

		int taskId = ActConventionManager.getTaskId(actConventionTask.getTaskType(), actConventionTask.getNum2());
		UserActConventionTask userActConventionTask = ActConventionManager.getUserActConventionTask(userId, taskId);
		if (userActConventionTask == null || userActConventionTask.getCurP() < actConventionTask.getNum1()) {
			return ErrorWord.INVALID_OPERATION;
		}

		JsonArray gainTaskArray = userActConventionTask.getGetRewardArray();
		if (gainTaskArray.contains(taskDbId)) {
			return ErrorWord.REPEATED_OPERATION; // 重复领取
		}
		// 执行逻辑 执行逻辑
		PBUserData.Builder pbUserData = response.getUserBuilder();
		RewardManager.addReward(userInfo, actConventionTask.getReward(), pbUserData, LogType.ACT_CONVENTION_COMPLETE_TASK_REWARD, taskDbId);
		gainTaskArray.add(taskDbId);
		userActConventionTask.putGetReward(gainTaskArray.toString());
		//if (MainTaskManager.isResetNumByTaskType(actConventionTask.getTaskType())) {
		//	userActConventionTask.putCurP(0);// 某任务类型的进度值,是否在领取完奖励需要重置
		//}
		userActConventionTask.update();
		ProtoDataUtils.updatePBUserData(pbUserData, userActConventionTask);
		return response;
	}

	// CMD_GAME_ACT_DAILY_RAFFLE_DRAW = 80052; // 每日特惠充值抽奖
	public static Object CMD_GAME_ACT_DAILY_RAFFLE_DRAW(RequestParam clientParam) throws Exception {
		CSGameActDailyRaffleDrawResponse.Builder response = CSGameActDailyRaffleDrawResponse.newBuilder();
		long userId = clientParam.getUserId();
		UserInfo userInfo = GameUser.getUserInfo(userId);

		if (!SystemManager.checkModuleOpen(userInfo, SystemConstant.SYSTEM_MODULE_ID_DAILY_RAFFLE_DRAW)) {
			return ErrorWord.MODULE_LOCKED;
		}

		UserDailyRaffleDraw userDailyRaffleDraw = ActManager.getUserDailyRaffleDraw(userInfo.getId());

		if (userDailyRaffleDraw.isFinishDraw()) { // 全部完成
			return ErrorWord.INVALID_OPERATION;
		}

		JsonArray postListArray = userDailyRaffleDraw.getPostListArray();
		int groupId = userDailyRaffleDraw.getGroupId();
		List<RaffleDraw> raffleDrawList = ActManager.getRaffleDrawList(groupId);
		if (raffleDrawList == null || postListArray.size() >= raffleDrawList.size()) {
			return ErrorWord.REPEATED_OPERATION;
		}

		List<RewardItem> costItems = CommonUtils.takeReawrdItemFromStr(AllParam.RAFFLE_ITEM_USE);
		if (!BagManager.checkNeedItemNum(userInfo, costItems)) {
			return ErrorWord.ITEM_LACK; // 道具不足
		}

		// 执行逻辑
		PBUserData.Builder pbUserData = response.getUserBuilder();
		List<RewardItem> rewardItemList = new ArrayList<>();
		if (postListArray.size() + 1 == raffleDrawList.size()) { // 最后一个
			RaffleDraw raffleDraw = raffleDrawList.stream().filter(x -> x.getSortId() == 1).findFirst().orElse(null);
			if (raffleDraw == null) {
				return ErrorWord.NOT_DATA;
			}

			if (postListArray.contains(raffleDraw.getSortId())) { // 大奖只有1个
				return ErrorWord.REPEATED_OPERATION;
			}
			postListArray.add(raffleDraw.getSortId());
			rewardItemList.addAll(CommonUtils.takeReawrdItemFromStr(raffleDraw.getReward()));
			userDailyRaffleDraw.putResetTime(TimeUtils.getCurTime());
		} else { // 随机1个（已获得得和大奖除外）
			List<RaffleDraw> availableList = raffleDrawList.stream().filter(rd -> !postListArray.contains(rd.getSortId()) && rd.getSortId() != 1).toList();
			if (availableList.isEmpty()) {
				return ErrorWord.NOT_DATA;
			}
			int[] rates = new int[availableList.size()];
			for (int i=0; i< availableList.size(); i++)  {
				rates[i] = availableList.get(i).getRate();
			}
			int randon = Tool.getWeightIndex(rates);
			RaffleDraw raffleDraw = availableList.get(randon);// 随机
			postListArray.add(raffleDraw.getSortId());
			rewardItemList.addAll(CommonUtils.takeReawrdItemFromStr(raffleDraw.getReward()));
		}

		RewardManager.subReward(userInfo, costItems, pbUserData, LogType.ACT_RAFFLE_DRAW);// 扣除
		RewardManager.addReward(userInfo, rewardItemList, pbUserData, LogType.ACT_RAFFLE_DRAW);// 奖励
		userDailyRaffleDraw.putPostList(postListArray.toString());
		userDailyRaffleDraw.update();
		ProtoDataUtils.updatePBUserData(pbUserData, userDailyRaffleDraw);

		return response;
	}

	// CMD_GAME_ACT_DAILY_OFFER_GIFT_INFO = 80053; // 每日特惠礼包
	public static Object CMD_GAME_ACT_DAILY_OFFER_GIFT_INFO(RequestParam clientParam) throws Exception {
		UserInfo userInfo = GameUser.getUserInfo(clientParam.getUserId());
		if (!SystemManager.checkModuleOpen(userInfo, SystemConstant.SYSTEM_MODULE_ID_DAILY_OFFER_GIFT)) {
			//return ErrorWord.MODULE_LOCKED;
		}
		CSGameActDailyOfferGiftInfoResponse.Builder response = CSGameActDailyOfferGiftInfoResponse.newBuilder();
		List<IapGift> iapGiftList = IapManager.getIapGiftTypeList(IapGift.TYPE_RECHARGE_ACT_DAILY_SPECIAL_OFFER);
		// 礼包未配置
		if (iapGiftList == null || iapGiftList.isEmpty()) {
			return ErrorWord.NOT_DATA;
		}
		long userId = clientParam.getUserId();
		PBUserData.Builder pbUserData = response.getUserBuilder();
		for (IapGift iapGift : iapGiftList) {
			UserIapGift userIapGift = IapManager.getUserIapGift(userId, iapGift.getId());
			if (userIapGift != null) {
				ProtoDataUtils.updatePBUserData(pbUserData, userIapGift,true);
			} else {
				userIapGift = new UserIapGift(userId, iapGift.getId());
				ProtoDataUtils.updatePBUserData(pbUserData, userIapGift,true);
			}
		}
		return response;
	}

	// CMD_GAME_ACT_DAILY_PASS_INFO = 80017; // 高级签到主界面信息
	public static Object CMD_GAME_ACT_DAILY_PASS_INFO(RequestParam clientParam) throws Exception {
		CsGameAct.CSGameActDailyPassInfoResponse.Builder response = CsGameAct.CSGameActDailyPassInfoResponse.newBuilder();
		UserDailyPass userDailyPass = ActManager.getUserDailyPass(clientParam.getUserId());
		PBUserData.Builder pbUserData = response.getUserBuilder();
		ProtoDataUtils.updatePBUserData(pbUserData, userDailyPass, true);
		return response;
	}



	// CMD_GAME_ACT_DAILY_PASS_SIGN_UP = 80018; // 高级签到 签到或者补签
	public static Object CMD_GAME_ACT_DAILY_PASS_SIGN_UP(RequestParam clientParam) throws Exception {
		CSGameActDailyPassSignUpRequest request = CSGameActDailyPassSignUpRequest.parseFrom(clientParam.getData());
		CSGameActDailyPassSignUpResponse.Builder  response = CSGameActDailyPassSignUpResponse.newBuilder();
		long userId = clientParam.getUserId();
		int index = request.getDay(); // 领取哪一天的奖励下标
		int type = request.getType();

		UserInfo userInfo = GameUser.getUserInfo(userId);
		if (!SystemManager.checkModuleOpen(userInfo, SystemConstant.SYSTEM_MODULE_ID_DAILY_PASS)) {
			return ErrorWord.MODULE_LOCKED;
		}

		PBUserData.Builder pbUserData = response.getUserBuilder();
		UserDailyPass userDailyPass = ActManager.getUserDailyPass(userId);
		UserExtInfo userExtInfo = GameUser.getUserExtInfo(userId);
		// 有效期未到无法进行签到
		boolean checkDailyPassValid = ActManager.checkDailyPassValid(userDailyPass.getGroupId(), userExtInfo.getRegisterTime());
		if (!checkDailyPassValid) { return ErrorWord.INVALID_OPERATION;}
		// 获取期数具体对应天数奖励配置
		DailyPassReward dailyPassGroupReward = ActManager.getDailyPassGroupReward(userDailyPass.getGroupId(), index);
		if (dailyPassGroupReward == null) return ErrorWord.NOT_DATA_5;
		// 判断是否有奖励可以领取
		DailyPass configByGroupId = ActManager.getDailyPassConfigByGroupId(userDailyPass.getGroupId());
		if(configByGroupId == null) return ErrorWord.NOT_DATA_1;
		// 判断今日是什么时候
		int diffDay = TimeUtils.getDiffDay(userExtInfo.getRegisterTime(), TimeUtils.getCurTime()) + 1; // 算上注册当天间隔天数
		int startDay = diffDay - configByGroupId.getStartDay();
		if(index <= 0 && index > startDay){ // 比当前天数还大或者参数不小于等于0不合法
			return ErrorWord.BAD_PARAM;
		}
		// 判断是否有购买高级礼包
		UserIapGift userIapGift = IapManager.getUserIapGift(userInfo.getId(), configByGroupId.getIapId());
		boolean isBuyPass = userIapGift != null && userIapGift.getNum() > 0;

		List<RewardItem> rewardItemList = new ArrayList<>();
		JsonArray signListArray = userDailyPass.getSignListArray();
		JsonArray signList2Array = userDailyPass.getSignList2Array();
		boolean contains = userDailyPass.getSignListArray().contains(index);  // 判断传进来的天数是否有领取免费奖励
		boolean contains2 = userDailyPass.getSignList2Array().contains(index); //  判断传进来的天数是否有领取战令奖励
		if (type == 0){  // 领奖
			// 普通奖励领取过，没购买高级奖励 不能再次领取
			if (contains && !isBuyPass) return ErrorWord.INVALID_OPERATION;
			if (contains && contains2) {  // 如果两个都领取过直接不能领取
				return ErrorWord.ALREADY_MAX;
			}
			// 如果没有领取过免费奖励,且天数大于等于当天，则需要补签才行
			if(!contains && index < startDay) return ErrorWord.INVALID_OPERATION;
		}else{  // 补签
			// 判断补签档位合法性 只能补签之前的天数
			if(startDay <= index){
				return ErrorWord.INVALID_OPERATION;
			}
			// 判断是否领取过奖励,领取过的不能补签
			if (contains || contains2) return ErrorWord.INVALID_OPERATION;
			//判断道具是否足够
			List<RewardItem> costItems = RewardManager.itemsToList(AllParam.SUPPLEMENTARY_SIGN_IN);
			if (!BagManager.checkNeedItemNum(userInfo,costItems)) {
				return ErrorWord.ITEM_LACK;//道具不足
			}
			RewardManager.subReward(userInfo,  costItems, pbUserData,LogType.DAILY_PASS_SIGN_UP_COST);
		}

		// 可以封装奖励然后设置了
		if (!contains){
			rewardItemList.addAll(RewardManager.itemsToList(dailyPassGroupReward.getReward1()));
			signListArray.add(index);
			userDailyPass.putSignList(signListArray.toString());
		}
		if (!contains2 && isBuyPass){
			rewardItemList.addAll(RewardManager.itemsToList(dailyPassGroupReward.getReward2()));
			signList2Array.add(index);
			userDailyPass.putSignList2(signList2Array.toString());
		}
		userDailyPass.update();
		// 更新用户数据和返回奖励
		if (!rewardItemList.isEmpty()) {
			RewardManager.addReward(userInfo, rewardItemList, pbUserData, LogType.DAILY_PASS_REWARD);
			ProtoDataUtils.updatePBUserData(pbUserData, userDailyPass,true);
		}
		return response;
	}
}
